package com.example.casesys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.casesys.dto.CaseDTO;
import com.example.casesys.dto.CaseInfoDTO;
import com.example.casesys.dto.CaseRequestParams;
import com.example.casesys.dto.UserDTO;
import com.example.casesys.entity.CaseInfo;
import com.example.casesys.entity.EvidInfo;
import com.example.casesys.mapper.CaseInfoMapper;
import com.example.casesys.mapper.EvidInfoMapper;
import com.example.casesys.service.CaseInfoService;
import com.example.casesys.utils.ExportExcel;
import com.example.casesys.utils.UserHolder;
import com.example.casesys.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 案件信息表 服务实现类
 * </p>
 *
 * @author hongren
 * @since 2023-09-11
 */
@Service
@Slf4j
public class CaseInfoServiceImpl extends ServiceImpl<CaseInfoMapper, CaseInfo> implements CaseInfoService {

    private static final Integer PAGE_SIZE = 13;
    @Resource
    private CaseInfoMapper caseInfoMapper;

    @Resource
    private EvidInfoMapper evidInfoMapper;

    /**
     * 查询案件信息(根据条件筛选)
     *
     * @return {@link Result}
     */
    @Override
    public Result selectCase(Integer current, CaseRequestParams params, HttpSession session) {
        UserDTO userDTO = UserHolder.getUser(session);

        Integer accType = userDTO.getAccType();
        Integer userId = userDTO.getId();

        long caseCount;
        List<CaseInfo> caseInfos;
        List<String> caseChargesList = caseInfoMapper.selectCaseCharges();
        List<String> acceptOrgList = caseInfoMapper.selectAcceptOrg();
        List<String> casePrgList = caseInfoMapper.selectCasePrg();
        Page<CaseInfo> page = Page.of(current, PAGE_SIZE);
        QueryWrapper<CaseInfo> queryWrapper = new QueryWrapper<>();
        if (!params.isEmpty()) {
            Map<String, Object> stringObjectMap = BeanUtil.beanToMap(params, true, true);
            stringObjectMap.forEach((key, value) -> {
                if ("case_begin".equals(key) && String.valueOf(value) != null) {
                    queryWrapper.ge(key, String.valueOf(value));
                }
                if ("case_end".equals(key) && String.valueOf(value) != null) {
                    queryWrapper.le("case_begin", String.valueOf(value));
                }
                if ("case_charges".equals(key) || "accept_org".equals(key) || ("case_prg").equals(key)) {
                    queryWrapper.eq(key, String.valueOf(value));
                }
            });
        }
        switch (accType) {
            case 0:
//              查询本人的案件
                queryWrapper.eq("user_number", userId);
                break;
            case 1:
//              查询该部门的所有案件
                String department = userDTO.getDepartment();
                queryWrapper.eq("accept_org", department);
                break;
            case 2:
//              查询所有案件
                break;
            default:
                return Result.fail().message("账号类型异常！");
        }

        Page<CaseInfo> selectPage = caseInfoMapper.selectPage(page, queryWrapper);
        caseInfos = selectPage.getRecords();
        caseCount = selectPage.getTotal();
        if (caseInfos == null || caseInfos.isEmpty()) {
            return Result.fail().message("未查询到数据！");
        }
        CaseDTO caseDTO = new CaseDTO();
        log.info("案件信息====>{}", caseInfos);
        caseDTO.setCaseList(caseInfos);
        caseDTO.setCaseCount(caseCount);
        caseDTO.setCaseChargesList(caseChargesList);
        caseDTO.setAcceptOrgList(acceptOrgList);
        caseDTO.setCasePrgList(casePrgList);
        return Result.ok(caseDTO).message("查询成功！");
    }

    /**
     * 添加案件
     *
     * @param caseInfo 案件对象
     * @return {@link Result}
     */
    @Override
    public Result addCase(CaseInfo caseInfo, HttpSession session) {
        UserDTO userDTO = UserHolder.getUser(session);
        String department = userDTO.getDepartment();
        try {
            caseInfo.setAcceptOrg(department);
            save(caseInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail().message("添加失败，请检查数据！");
        }
        return Result.ok().message("添加成功！");
    }

    /**
     * 更新案件
     *
     * @param caseInfo 更新参数（修改非null的参数）
     * @return {@link Result}
     */
    @Override
    public Result updateCase(CaseInfo caseInfo) {
        if (updateById(caseInfo)) {
            return Result.ok().message("修改成功！");
        }
        return Result.fail().message("修改失败!检查数据有效性！");
    }

    /**
     * 统计案件
     *
     * @return {@link Result}
     */
    @Override
    public Result countCase() {
        Map<String, Object> resMap = new HashMap<>();
        QueryWrapper<CaseInfo> wrapper = new QueryWrapper<>();
        LocalDate now = LocalDate.now();
        LocalDate beginTime = now.minusYears(0).withMonth(1).withDayOfMonth(1);
        LocalDate endTime = now.minusYears(-1).withMonth(1).withDayOfMonth(1);
//
        try {
//        根据案发地 select case_area , count(*) from tb_case_info group by case_area
            wrapper.select("case_area , count(*) as count")
                    .ge("case_begin", beginTime)
                    .le("case_begin", endTime)
                    .groupBy("case_area").orderByDesc("count");

            List<Map<String, Object>> areaMaps = caseInfoMapper.selectMaps(wrapper);
            resMap.put("area", areaMaps);
//        根据案件类型 select case_charges , count(*) from tb_case_info group by case_charges
            wrapper.clear();
            wrapper.select("case_charges , count(*) as count")
                    .ge("case_begin", beginTime)
                    .le("case_begin", endTime)
                    .groupBy("case_charges").orderByDesc("count");
            List<Map<String, Object>> typeMap = caseInfoMapper.selectMaps(wrapper);
            resMap.put("charges", typeMap);
//        根据各单位（办理中）（已办理）
//        select accept_org , case_prg , count(*) from tb_case_info group by accept_org , case_prg
            wrapper.clear();
            wrapper.select("accept_org , case_prg , count(*) as count")
                    .ge("case_begin", beginTime)
                    .le("case_begin", endTime)
                    .groupBy("accept_org , case_prg").orderByDesc("accept_org", "count");
            List<Map<String, Object>> orgMap = caseInfoMapper.selectMaps(wrapper);
            resMap.put("org", orgMap);
        } catch (Exception e) {
            return Result.fail().message("查询异常！请重试！");
        }
        return Result.ok(resMap).message("查询成功！");
    }

    /**
     * 逻辑删除
     *
     * @return {@link Result}
     */
    @Override
    public Result deleteCase(Long caseId) {

        try {
            int del = caseInfoMapper.deleteById(caseId);
            if (del <= 0) {
                return Result.fail().message("删除失败，请检查数据！");
            }
        } catch (Exception e) {
            return Result.fail().message("删除失败！服务器异常");
        }
        return Result.ok().message("删除成功！");
    }

    /**
     * 查询即将过期和已过期的案件
     *
     * @return
     */
    @Override
    public Result selectNearExpCase(HttpSession session) {
        QueryWrapper<CaseInfo> queryWrapper = new QueryWrapper();
        UserDTO user = UserHolder.getUser(session);
        Integer accType = user.getAccType();
        switch (accType) {
            case 0:
                queryWrapper.eq("user_number", user.getId());
                break;
            case 1:
                queryWrapper.eq("accept_org", user.getDepartment());
                break;
            case 2:
                break;
            default:
                return Result.fail().message("账号类型错误");
        }
        queryWrapper.eq("case_prg", "正在办理");
        List<CaseInfo> caseInfos = caseInfoMapper.selectList(queryWrapper);
        if (caseInfos.isEmpty()) {
            return Result.fail().message("当前没有即将过期和已过期的案件");
        }
        LocalDate nowTime = LocalDate.now();
        caseInfos.forEach(a -> {
            Long days = nowTime.until(a.getDeadlineWarn(), ChronoUnit.DAYS);
//            Long days = (long)Period.between(LocalDate.now(), a.getDeadlineWarn()).getDays();
            a.setNearExp(days);
        });
        return Result.ok(caseInfos);
    }

    /**
     * 案件数据导出成excel
     *
     * @param params
     * @param session
     */
    @Override
    public void exportCase(CaseRequestParams params, HttpSession session, HttpServletResponse response) {
        UserDTO userDTO = UserHolder.getUser(session);
        Integer accType = userDTO.getAccType();
        Integer userId = userDTO.getId();
        QueryWrapper<CaseInfo> queryWrapper = new QueryWrapper<>();
        if (!params.isEmpty()) {
            Map<String, Object> stringObjectMap = BeanUtil.beanToMap(params, true, true);
            stringObjectMap.forEach((key, value) -> {
                if ("case_begin".equals(key) && String.valueOf(value) != null) {
                    queryWrapper.ge(key, String.valueOf(value));
                }
                if ("case_end".equals(key) && String.valueOf(value) != null) {
                    queryWrapper.le("case_begin", String.valueOf(value));
                }
                if ("case_charges".equals(key) || "accept_org".equals(key) || ("case_prg").equals(key)) {
                    queryWrapper.eq(key, String.valueOf(value));
                }
            });
        }
        switch (accType) {
            case 0:
//              查询本人的案件
                queryWrapper.eq("user_number", userId);
                break;
            case 1:
//              查询该部门的所有案件
                String department = userDTO.getDepartment();
                queryWrapper.eq("accept_org", department);
                break;
            case 2:
//              查询所有案件
                break;
            default:
                break;
        }
        List<CaseInfo> caseInfosList = caseInfoMapper.selectList(queryWrapper);
        if (!caseInfosList.isEmpty()) {
            List<CaseInfoDTO> caseInfoDTOList = new ArrayList<>(caseInfosList.size());
            caseInfosList.forEach(caseInfo -> {
                CaseInfoDTO caseInfoDTO = BeanUtil.copyProperties(caseInfo, CaseInfoDTO.class);
                caseInfoDTOList.add(caseInfoDTO);
            });
            try {
                ExportExcel.export(caseInfoDTOList, response);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 查询最近一周案件证据上传及修改情况
     *
     * @param currentPage 页码值
     * @param session
     * @return
     */
    @Override
    public Result selectCaseInfo(Integer currentPage, HttpSession session) {

        UserDTO userDTO = UserHolder.getUser(session);
        QueryWrapper<CaseInfo> queryWrapper = new QueryWrapper<>();
        Integer accType = userDTO.getAccType();
        switch (accType) {
            case 1:
                String department = userDTO.getDepartment();
                queryWrapper.eq("accept_org", department);
                break;
            case 2:
                break;
            default:
                return Result.fail().message("您没有权限！");
        }
        QueryWrapper<EvidInfo> wrapper = new QueryWrapper<>();
        LocalDateTime dateTime = LocalDateTime.now().plusDays(-7);
        wrapper.select("DISTINCT case_id").ge("upload_time", dateTime).or().ge("update_time", dateTime);
        List<EvidInfo> evidInfoList = evidInfoMapper.selectList(wrapper);
        if (evidInfoList.isEmpty()) {
            return Result.fail().message("未查询到数据！");
        }
        List<String> idList = new ArrayList<>(evidInfoList.size());
        evidInfoList.forEach(evidInfo -> {
            idList.add(evidInfo.getCaseId());
        });
        queryWrapper.in("case_id", idList);
        IPage<CaseInfo> page = new Page<>(currentPage, PAGE_SIZE);
        IPage<CaseInfo> casePage = caseInfoMapper.selectPage(page, queryWrapper);
        if (casePage.getTotal() == 0) {
            return Result.fail().message("未查询到数据！");
        }
        return Result.ok(casePage);
    }
}
